{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7db77fa0-f887-4f36-acc1-595551c6bdf8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# File: curtain.ipynb\n",
    "# Code: Claude Code and Codex\n",
    "# Review: Ryoichi Ando (ryoichi.ando@zozo.com)\n",
    "# License: Apache v2.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1341564f-3d1b-4674-b8c6-b6e4eb707764",
   "metadata": {},
   "outputs": [],
   "source": [
    "from frontend import App\n",
    "\n",
    "# create an app\n",
    "app = App.create(\"curtain\")\n",
    "\n",
    "# create a square sheet mesh\n",
    "V, F = app.mesh.square(res=64, ex=[0, 0, 1], ey=[0, 1, 0])\n",
    "app.asset.add.tri(\"sheet\", V, F)\n",
    "\n",
    "# create a sphere mesh\n",
    "V, F = app.mesh.icosphere(r=0.5, subdiv_count=4)\n",
    "app.asset.add.tri(\"sphere\", V, F)\n",
    "\n",
    "# create a small sphere mesh\n",
    "V, F = app.mesh.icosphere(r=0.25, subdiv_count=3)\n",
    "sphere = app.asset.add.tri(\"small-sphere\", V, F)\n",
    "\n",
    "# create a scene\n",
    "scene = app.scene.create()\n",
    "\n",
    "# add multiple sheets as curtains with spacing\n",
    "space = 0.25\n",
    "for i in range(15):\n",
    "    obj = scene.add(\"sheet\")\n",
    "    obj.param.set(\"strain-limit\", 0.05)\n",
    "    obj.at(i * space, 0, 0)\n",
    "    # set fiber directions for Baraff-Witkin\n",
    "    obj.direction([0, 1, 0], [0, 0, 1])\n",
    "    # pin top edge of each sheet\n",
    "    obj.pin(obj.grab([0, 1, 0]))\n",
    "\n",
    "# add moving sphere that will push through the curtains\n",
    "sphere = scene.add(\"sphere\")\n",
    "(\n",
    "    sphere.color(0.75, 0.75, 0.75)\n",
    "    .at(-1, 0, 0)\n",
    "    .jitter()\n",
    "    .pin()\n",
    "    .move_by([8, 0, 0], 0, 5)\n",
    ")\n",
    "\n",
    "# compile the scene and report stats\n",
    "scene = scene.build().report()\n",
    "\n",
    "# preview the initial scene\n",
    "scene.preview()\n",
    "\n",
    "# create a new session with the compiled scene\n",
    "session = app.session.create(scene)\n",
    "\n",
    "# build this session\n",
    "session = session.build()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cf30d202-48ac-4c37-b896-cbcf76432c76",
   "metadata": {},
   "outputs": [],
   "source": [
    "# start the simulation and live-preview the results\n",
    "session.start().preview()\n",
    "\n",
    "# also show simulation logs in realtime\n",
    "session.stream()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2aa65b45-4226-40cd-8e57-febbb11f6fe6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# create an animation from the simulation results\n",
    "session.animate()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cb760aaa-cb65-476c-97f2-60891eda4b76",
   "metadata": {},
   "outputs": [],
   "source": [
    "# export the animation to file\n",
    "session.export.animation()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a728b4eb-916c-4f57-a485-c6c0e8e06c32",
   "metadata": {},
   "outputs": [],
   "source": [
    "# this is for CI\n",
    "if app.ci:\n",
    "    assert session.finished()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
